package com.leyou.item.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.leyou.common.enums.ExceptionEnum;
import com.leyou.common.exception.LeYouException;
import com.leyou.common.pojo.PageResult;
import com.leyou.item.dto.CartDTO;
import com.leyou.item.mapper.SkuMapper;
import com.leyou.item.mapper.SpuDetailMapper;
import com.leyou.item.mapper.SpuMapper;
import com.leyou.item.mapper.StockMapper;
import com.leyou.item.pojo.*;
import com.leyou.item.vo.SpuDTO;
import com.leyou.item.vo.SpuVO;
import com.leyou.utils.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.*;
import java.util.stream.Collectors;


@Slf4j
@Transactional
@Service
public class GoodsService {

    @Autowired
    private SpuDetailMapper spuDetailMapper;


    @Autowired
    private SpuMapper spuMapper;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private BrandService brandService;

    @Autowired
    private SkuMapper skuMapper;

    @Autowired
    private StockMapper stockMapper;

    @Autowired
    private AmqpTemplate amqpTemplate;

    /**
     * @param page
     * @param rows
     * @param saleable
     * @param key
     * @return
     */

    public PageResult<SpuVO> querySpuByPaeg(Integer page, Integer rows, Boolean saleable, String key) {
        // 分页
        PageHelper.startPage(page, rows);
        Example example = new Example(Spu.class);
        Example.Criteria criteria = example.createCriteria();
        // 过滤
        // 搜索字段过滤
        if (StringUtils.isNotBlank(key)) {
            criteria.andLike("name", "%" + key + "%");
        }
        // 上下架过滤
        if (saleable != null) {
            criteria.andEqualTo("saleable", saleable);
        }
        // 默认排序
        example.setOrderByClause("last_update_time desc ");

        // 查询
        List<Spu> spuList = spuMapper.selectByExample(example);

        // 判断
        if (CollectionUtils.isEmpty(spuList)) {
            throw new LeYouException(ExceptionEnum.GOODS_NOT_FOUND);
        }

        // 解析分类和品牌的名称
        List<SpuVO> list = loadCategoryAndBranName(spuList);

        // 解析分页结果
        PageInfo<Spu> spuPageInfo = new PageInfo<>(spuList);


        return new PageResult<SpuVO>(spuPageInfo.getTotal(), list);
    }


    /**
     * @param spuList
     * @return
     */
    private List<SpuVO> loadCategoryAndBranName(List<Spu> spuList) {
        List<SpuVO> spuVOList = new ArrayList<>();
        for (Spu spu : spuList) {
            // 处理分类名称过
            List<Long> longList = Arrays.asList(spu.getCid1(), spu.getCid2(), spu.getCid3());
            List<Category> categoryList = categoryService.queryByIds(longList);
            List<String> stringList = categoryList.stream().map(Category::getName).collect(Collectors.toList());
            SpuVO spuVO = new SpuVO();
            BeanUtils.copyProperties(spu, spuVO);
            spuVO.setCname(StringUtils.join(stringList, "/"));
            Brand brand = brandService.queryById(spu.getBrandId());
            spuVO.setBname(brand.getName());
            spuVOList.add(spuVO);
        }

        return spuVOList;
    }

    /**
     * @param spuDTO
     */
    @Transactional(rollbackFor = Exception.class)
    public void saveGoods(SpuDTO spuDTO) {
        // 新增spu
        Spu spu = new Spu();
        BeanUtils.copyProperties(spuDTO, spu);
        spu.setId(null);
        spu.setCreateTime(new Date());
        spu.setLastUpdateTime(new Date());
        spu.setSaleable(true);
        spu.setValid(false);

        int insert = spuMapper.insert(spu);
        if (insert != 1) {
            throw new LeYouException(ExceptionEnum.GOODS_SAVE_ERROR);
        }
        // 新增 detail
        SpuDetail spuDetail = spuDTO.getSpuDetail();
        spuDetail.setSpuId(spu.getId());
        int spuDeta = spuDetailMapper.insert(spuDetail);
        if (spuDeta != 1) {
            throw new LeYouException(ExceptionEnum.GOODS_SAVE_ERROR);
        }

        List<Stock> stockList = new ArrayList<>();
        // 新增 sku
        List<Sku> skus = spuDTO.getSkus();
        for (Sku skuEvery : skus) {
            skuEvery.setCreateTime(new Date());
            skuEvery.setLastUpdateTime(skuEvery.getCreateTime());
            skuEvery.setSpuId(spu.getId());

            insert = skuMapper.insert(skuEvery);
            if (insert != 1) {
                throw new LeYouException(ExceptionEnum.GOODS_SAVE_ERROR);
            }
            // 新增 库存
            Stock stock = new Stock();
            stock.setSkuId(skuEvery.getId());
            stock.setStock(skuEvery.getStock());

            stockList.add(stock);
        }
        insert = stockMapper.insertList(stockList);

        if (insert != stockList.size()) {
            throw new LeYouException(ExceptionEnum.GOODS_SAVE_ERROR);
        }

        // 发送消息
        amqpTemplate.convertAndSend("item.create", spu.getId());
    }

    /**
     * 修改商品
     *
     * @param spuDTO
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateGoods(SpuDTO spuDTO) {
        if (spuDTO == null || spuDTO.getId() == null) {
            throw new LeYouException(ExceptionEnum.GOODS_ID_CANNOT_BE_NULL);
        }
        // 删除sku 和 stock
        Sku skuQuery = new Sku();
        skuQuery.setSpuId(spuDTO.getId());
        List<Sku> skuList = skuMapper.select(skuQuery);
        if (!CollectionUtils.isEmpty(skuList)) {
            // 删除 sku
            skuMapper.delete(skuQuery);
            // 删除stock
            List<Long> idList = skuList.stream().map(Sku::getId).collect(Collectors.toList());
            int delete = stockMapper.deleteByIdList(idList);

        }
        // 修改sku
        spuDTO.setValid(null);
        spuDTO.setSaleable(null);
        spuDTO.setLastUpdateTime(new Date());
        spuDTO.setCreateTime(null);
        Spu spu = new Spu();
        BeanUtils.copyProperties(spuDTO, spu);
        int count = spuMapper.updateByPrimaryKeySelective(spu);
        if (count != 1) {
            throw new LeYouException(ExceptionEnum.GOODS_UPDATE_ERROR);
        }
        // 修改 detail
        count = spuDetailMapper.updateByPrimaryKeySelective(spuDTO.getSpuDetail());
        if (count != 1) {
            throw new LeYouException(ExceptionEnum.GOODS_UPDATE_ERROR);
        }
        // 新增sku 和 stock
        List<Stock> stockList = new ArrayList<>();
        // 新增 sku
        List<Sku> skus = spuDTO.getSkus();
        for (Sku skuEvery : skus) {
            skuEvery.setCreateTime(new Date());
            skuEvery.setLastUpdateTime(skuEvery.getCreateTime());
            skuEvery.setSpuId(spu.getId());

            count = skuMapper.insert(skuEvery);
            if (count != 1) {
                throw new LeYouException(ExceptionEnum.GOODS_SAVE_ERROR);
            }
            // 新增 库存
            Stock stock = new Stock();
            stock.setSkuId(skuEvery.getId());
            stock.setStock(skuEvery.getStock());

            stockList.add(stock);
        }
        count = stockMapper.insertList(stockList);

        if (count != stockList.size()) {
            throw new LeYouException(ExceptionEnum.GOODS_SAVE_ERROR);
        }

        // 发送消息
        amqpTemplate.convertAndSend("item.update", spu.getId());

    }


    public SpuDetail queryDetailByid(Long spuId) {

        SpuDetail spuDetail = spuDetailMapper.selectByPrimaryKey(spuId);

        if (spuDetail == null) {
            throw new LeYouException(ExceptionEnum.SPUDETAIL_NOT_FOUND);
        }
        return spuDetail;
    }

    public List<Sku> querySkuBySpuId(Long id) throws Exception {
        Sku sku = new Sku();
        sku.setSpuId(id);

        List<Sku> select = skuMapper.select(sku);

        if (CollectionUtils.isEmpty(select)) {
            throw new LeYouException(ExceptionEnum.GOODS_SKU_NOT_FOUND);
        }

        //BeanUtils.copyProperties();
        // 查询库存
        List<Long> ids = select.stream().map(Sku::getId).collect(Collectors.toList());
        List<Stock> stockList = stockMapper.selectByIdList(ids);
        log.info("查询到的库存为：{}", JsonUtils.tostring(stockList));
        if (CollectionUtils.isEmpty(stockList)) {
            throw new LeYouException(ExceptionEnum.GOODS_STOCK_NOT_FOUND);
        }
        // 我们把stock 变成一个map, 其key是:sku的id, 值时库存值
        Map<Long, Integer> collect = stockList.stream().collect(Collectors.toMap(Stock::getSkuId, Stock::getStock));
        log.info("查询到的库存转换的map集合为：" + JsonUtils.tostring(collect));
        select.forEach(s -> s.setStock(collect.get(s.getId())));

        return select;

    }


    public List<Sku> querySkuBySpuIds(List<Long> ids) throws Exception {


        List<Sku> select = skuMapper.selectByIdList(ids);

        if (CollectionUtils.isEmpty(select)) {
            throw new LeYouException(ExceptionEnum.GOODS_SKU_NOT_FOUND);
        }

        // 查询库存
        List<Long> idsList = select.stream().map(Sku::getId).collect(Collectors.toList());

        List<Stock> stockList = stockMapper.selectByIdList(idsList);
        log.info("查询到的库存为：{}", JsonUtils.tostring(stockList));
        if (CollectionUtils.isEmpty(stockList)) {
            throw new LeYouException(ExceptionEnum.GOODS_STOCK_NOT_FOUND);
        }
        // 我们把stock 变成一个map, 其key是:sku的id, 值时库存值
        Map<Long, Integer> collect = stockList.stream().collect(Collectors.toMap(Stock::getSkuId, Stock::getStock));
        log.info("查询到的库存转换的map集合为：" + JsonUtils.tostring(collect));
        select.forEach(s -> s.setStock(collect.get(s.getId())));

        return select;

    }

    /**
     * 根据主键查询 spu的信息
     *
     * @param id
     * @return
     */
    public SpuDTO querySpuById(Long id) throws Exception {
        SpuDTO spuDTO = new SpuDTO();
        Spu spu = this.spuMapper.selectByPrimaryKey(id);
        if (spu == null) {
            throw new LeYouException(ExceptionEnum.GOODS_NOT_FOUND);
        }
        BeanUtils.copyProperties(spu, spuDTO);
        // 查询spuDetail
        SpuDetail spuDetail = this.queryDetailByid(id);
        // 查询 sku
        List<Sku> skus = this.querySkuBySpuId(id);
        spuDTO.setSkus(skus);

        spuDTO.setSpuDetail(spuDetail);
        return spuDTO;
    }

    /**
     * 减少库存的操作
     *
     * @param carts
     */
    @Transactional(rollbackFor = Exception.class)
    public void decreaseStock(List<CartDTO> carts) {

        for (CartDTO cart : carts) {
            // 减少库存
            int stock = stockMapper.decreaseStock(cart.getSkuId(), cart.getNum());
            if (stock != 1) {
                throw new LeYouException(ExceptionEnum.STOCK_NOT_ENOUGH);
            }
            log.info("[商品微服务] 减少库存操作 skuId:{} ,减少数量: {}, 执行结果:{}", cart.getSkuId(), cart.getNum(), stock);
        }
    }
}
